﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace RemoteDesktop
{
    internal class MouseHook
    {
        // 声明鼠标钩子的类型
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        // 声明钩子回调函数的类型
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll")]
        public static extern bool ExitWindowsEx(uint uFlags, uint dwReason);

        [DllImport("user32.dll")]
        public static extern bool BlockInput(bool bBlock);

        const uint EWX_LOGOFF = 0x00000000;
        // 声明鼠标钩子的常量
        private const int WH_MOUSE_LL = 14;

        // 声明钩子过滤的函数指针类型
        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

        // 实例化钩子过滤函数
        private LowLevelMouseProc _proc;

        // 钩子句柄
        private IntPtr _hookID = IntPtr.Zero;

        public MouseHook()
        {
            // 实例化钩子过滤函数并开始监听鼠标事件
            _proc = HookCallback;
            _hookID = SetWindowsHookEx(WH_MOUSE_LL, _proc, IntPtr.Zero, 0);
        }

        // 钩子过滤函数
        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                // 这里可以根据wParam判断鼠标事件类型
                // 例如，wParam == (IntPtr)WM_MOUSEMOVE 时，表示鼠标移动
                // lParam是一个指向MOUSEHOOKSTRUCT的指针，包含了鼠标的信息

                // 可以在这里编写代码来响应鼠标形状变化
                // 如果需要获取鼠标当前形状，可以使用GetCursorInfo函数

                // 调用下一个钩子过滤函数
                return CallNextHookEx(_hookID, nCode, wParam, lParam);
            }
            return IntPtr.Zero;
        }

        // 释放钩子
        public void Dispose()
        {
            if (_hookID != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_hookID);
                _hookID = IntPtr.Zero;
            }
        }
        public static void UnlockComputer()
        {
            BlockInput(false); // 允许模拟输入
            ExitWindowsEx(EWX_LOGOFF, 0); // 模拟注销操作来解锁电脑
            BlockInput(true); // 禁止模拟输入
        }
    }
}
